package utils

import (
	"crypto/md5"
	"fmt"
	"strconv"
	"strings"

	"golang.org/x/crypto/bcrypt"
)

// HashPassword 使用bcrypt加密密码
func HashPassword(password string) (string, error) {
	bytes, err := bcrypt.GenerateFromPassword([]byte(password), bcrypt.DefaultCost)
	return string(bytes), err
}

// CheckPasswordHash 检查密码是否匹配
func CheckPasswordHash(password, hash string) bool {
	err := bcrypt.CompareHashAndPassword([]byte(hash), []byte(password))
	return err == nil
}

// MD5 计算字符串的MD5值
func MD5(str string) string {
	h := md5.New()
	h.Write([]byte(str))
	return fmt.Sprintf("%x", h.Sum(nil))
}

// StringToUint 字符串转uint
func StringToUint(s string) uint {
	id, _ := strconv.ParseUint(s, 10, 32)
	return uint(id)
}

// StringToUint64 字符串转uint64
func StringToUint64(s string) uint64 {
	id, _ := strconv.ParseUint(s, 10, 64)
	return id
}

// StringSliceToUintSlice 字符串切片转uint切片
func StringSliceToUintSlice(strs []string) []uint {
	var result []uint
	for _, s := range strs {
		result = append(result, StringToUint(s))
	}
	return result
}

// StringSliceToUint64Slice 字符串切片转uint64切片
func StringSliceToUint64Slice(strs []string) []uint64 {
	var result []uint64
	for _, s := range strs {
		result = append(result, StringToUint64(s))
	}
	return result
}

// UintSliceToStringSlice uint切片转字符串切片
func UintSliceToStringSlice(uints []uint) []string {
	var result []string
	for _, u := range uints {
		result = append(result, strconv.FormatUint(uint64(u), 10))
	}
	return result
}

// Uint64SliceToStringSlice uint64切片转字符串切片
func Uint64SliceToStringSlice(uints []uint64) []string {
	var result []string
	for _, u := range uints {
		result = append(result, strconv.FormatUint(u, 10))
	}
	return result
}

// ContainsString 检查字符串切片是否包含指定字符串
func ContainsString(slice []string, item string) bool {
	for _, s := range slice {
		if s == item {
			return true
		}
	}
	return false
}

// ContainsUint 检查uint切片是否包含指定uint
func ContainsUint(slice []uint, item uint) bool {
	for _, s := range slice {
		if s == item {
			return true
		}
	}
	return false
}

// ContainsUint64 检查uint64切片是否包含指定uint64
func ContainsUint64(slice []uint64, item uint64) bool {
	for _, s := range slice {
		if s == item {
			return true
		}
	}
	return false
}

// RemoveString 从字符串切片中移除指定字符串
func RemoveString(slice []string, item string) []string {
	var result []string
	for _, s := range slice {
		if s != item {
			result = append(result, s)
		}
	}
	return result
}

// RemoveUint 从uint切片中移除指定uint
func RemoveUint(slice []uint, item uint) []uint {
	var result []uint
	for _, s := range slice {
		if s != item {
			result = append(result, s)
		}
	}
	return result
}

// RemoveUint64 从uint64切片中移除指定uint64
func RemoveUint64(slice []uint64, item uint64) []uint64 {
	var result []uint64
	for _, s := range slice {
		if s != item {
			result = append(result, s)
		}
	}
	return result
}

// UniqueString 去重字符串切片
func UniqueString(slice []string) []string {
	keys := make(map[string]bool)
	var list []string
	for _, entry := range slice {
		if _, value := keys[entry]; !value {
			keys[entry] = true
			list = append(list, entry)
		}
	}
	return list
}

// UniqueUint 去重uint切片
func UniqueUint(slice []uint) []uint {
	keys := make(map[uint]bool)
	var list []uint
	for _, entry := range slice {
		if _, value := keys[entry]; !value {
			keys[entry] = true
			list = append(list, entry)
		}
	}
	return list
}

// UniqueUint64 去重uint64切片
func UniqueUint64(slice []uint64) []uint64 {
	keys := make(map[uint64]bool)
	var list []uint64
	for _, entry := range slice {
		if _, value := keys[entry]; !value {
			keys[entry] = true
			list = append(list, entry)
		}
	}
	return list
}

// JoinString 用分隔符连接字符串切片
func JoinString(slice []string, sep string) string {
	return strings.Join(slice, sep)
}

// JoinUint 用分隔符连接uint切片
func JoinUint(slice []uint, sep string) string {
	strSlice := UintSliceToStringSlice(slice)
	return strings.Join(strSlice, sep)
}

// JoinUint64 用分隔符连接uint64切片
func JoinUint64(slice []uint64, sep string) string {
	strSlice := Uint64SliceToStringSlice(slice)
	return strings.Join(strSlice, sep)
}

// SplitString 用分隔符分割字符串
func SplitString(str, sep string) []string {
	return strings.Split(str, sep)
}

// SplitStringToUint 用分隔符分割字符串并转为uint切片
func SplitStringToUint(str, sep string) []uint {
	strSlice := strings.Split(str, sep)
	return StringSliceToUintSlice(strSlice)
}

// SplitStringToUint64 用分隔符分割字符串并转为uint64切片
func SplitStringToUint64(str, sep string) []uint64 {
	strSlice := strings.Split(str, sep)
	return StringSliceToUint64Slice(strSlice)
}